﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Runtime.InteropServices;

namespace HovisPresent
{
	public partial class RunForm : UsefulForm
	{
		public RunPresentationOptions Options { get; set; }
		private Monitor primaryMonitorID;
		
		public RunForm() {
			InitializeComponent();
			Options = new RunPresentationOptions();
		}

		/// <summary>
		/// Handles the Load event of the RunForm control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void RunForm_Load(object sender, EventArgs e) {

			/// get hostname/ips
			string hostname = System.Net.Dns.GetHostName();
			string textHost = hostname;
			IPHostEntry ipEntry = Dns.GetHostByName(hostname);
			IPAddress [] addr = ipEntry.AddressList;
          
			for (int i = 0; i < addr.Length; i++)
				textHost+="/"+addr[i].ToString();

			localHostname.Text = textHost;

			// populate monitor controls
			for (int i = 0; i < Screen.AllScreens.Length; i++) {
				Screen s = Screen.AllScreens[i];
				string name = s.DeviceName;
				Win32Stuff.DISPLAY_DEVICE d = new Win32Stuff.DISPLAY_DEVICE();
				d.cb = Marshal.SizeOf(d);
				if (Win32Stuff.EnumDisplayDevices(s.DeviceName, 0, d, 0) != true)
					continue;

				if ((d.StateFlags & Win32Stuff.DISPLAY_DEVICE_MIRRORING_DRIVER) != 0)
					continue;

				name = d.DeviceString;

				if (s.Primary) {
					name += " (primary)";
					primaryMonitorID = (Monitor) i;
				}

				name = "#" + (i + 1) + " " + name;
				presentationMonitor.Items.Add(name);
				presenterMonitor.Items.Add(name);
			}

			UpdateUIFromOptions();
			UpdateNetworkControls();
		}

		/// <summary>
		/// The network type has changed by the user
		/// </summary>
		/// <param name="sender">The sender.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void networkTypeChanged(object sender, EventArgs e) {
			UpdateNetworkControls();
		}

		/// <summary>
		/// Updates the network controls enable/disable
		/// </summary>
		private void UpdateNetworkControls() {
			slaves.Enabled = networkMasterOrLocal.Checked == true;
		}

		/// <summary>
		/// Handles the Click event of the run control. Update the RunPresentationOptions to 
		/// mirror the UI settings
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void run_Click(object sender, EventArgs e) {
			if (!enablePresentationMonitor.Checked && !enablePresenterMonitor.Checked) {
				MessageBox.Show(this, "You must enable one or other view", "Error", MessageBoxButtons.OK,
								 MessageBoxIcon.Hand);
				DialogResult = DialogResult.None;
				return;
			}

			Options.NetworkMode = networkMasterOrLocal.Checked ? NetworkMode.LocalOrMaster : NetworkMode.Slave;
			Options.NetworkPort = (int) networkPort.Value;
			string[] slaveItems = slaves.Text.Trim().Split( new string[] {"\r\n"}, StringSplitOptions.RemoveEmptyEntries);
			Options.Slaves = new List<string>(slaveItems);

			// default, windowed mode
			Options.PresentationMonitor = Options.PresenterMonitor = Monitor.Monitor0;

			Options.PresentationMonitor = enablePresentationMonitor.Checked ? (Monitor) presentationMonitor.SelectedIndex : Monitor.noMonitor;
			Options.PresenterMonitor = enablePresenterMonitor.Checked ? (Monitor)presenterMonitor.SelectedIndex : Monitor.noMonitor;

			Options.ShowScriptByDefault = defaultShowScript.Checked;
		}

		/// <summary>
		/// Update the controls to reflect the Options object;
		/// </summary>
		private void UpdateUIFromOptions() {
			networkPort.Value = Options.NetworkPort;
			networkMasterOrLocal.Checked = Options.NetworkMode == NetworkMode.LocalOrMaster;
			networkSlave.Checked = Options.NetworkMode == NetworkMode.Slave;

			// limit monitor #
			if ((int)Options.PresentationMonitor >= Screen.AllScreens.Length)
				Options.PresentationMonitor = primaryMonitorID;
			if ((int)Options.PresenterMonitor >= Screen.AllScreens.Length)
				Options.PresenterMonitor = primaryMonitorID;

			if (Options.PresentationMonitor == Monitor.noMonitor && Options.PresenterMonitor == Monitor.noMonitor)
				Options.PresentationMonitor = primaryMonitorID;

			presentationMonitor.SelectedIndex = Options.PresentationMonitor==Monitor.noMonitor ? (int)primaryMonitorID : (int)Options.PresentationMonitor;
			presenterMonitor.SelectedIndex = Options.PresenterMonitor==Monitor.noMonitor ? (int)primaryMonitorID : (int)Options.PresenterMonitor;

			enablePresentationMonitor.Checked = Options.PresentationMonitor != Monitor.noMonitor;
			enablePresenterMonitor.Checked = Options.PresenterMonitor != Monitor.noMonitor;

			enablePresentationView_CheckedChanged(null, null);
			enablePresenterView_CheckedChanged(null, null);

			slaves.Text = "";
			foreach (string s in Options.Slaves) {
				if (slaves.Text != "")
					slaves.Text += "\r\n";
				slaves.Text += s;
			}

			defaultShowScript.Checked = Options.ShowScriptByDefault;
		}

		private void enablePresentationView_CheckedChanged(object sender, EventArgs e) {
			presentationMonitor.Enabled = enablePresentationMonitor.Checked;
		}

		private void enablePresenterView_CheckedChanged(object sender, EventArgs e) {
			presenterMonitor.Enabled = enablePresenterMonitor.Checked;
		}

	}
}
